/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef IPWM_REG_ACCESS_H
#define IPWM_REG_ACCESS_H

/*!
 * @file ipwm_reg_access.h
 * @brief This file declares or defines ipwm register access functions
 */

/*******Includes***************************************************************/
#include "ipwm_drv.h"

/*******Definitions************************************************************/
/*! @brief All channel event flag */
#define IPWM_STATUS_CHF_Msk              (0xFFUL)

/*! @brief All channel level */
#define IPWM_STATUS_LVL_Mask             (0xF00UL)

/*! @brief IPWM one channel sync ponit config width */
#define IPWM_SYNC_POINT_WIDTH            (0x02UL)

/*! @brief IPWM one channel SYNCOFF config width */
#define IPWM_SYNCONF_CONFIG_WIDTH        (0x8UL)

/*! @brief IPWM one channel modulo dither config width */
#define IPWM_MODDITHER_CONFIG_WIDTH      (0x8UL)

/*! @brief IPWM one channel match dir config width */
#define IPWM_MATCH_DIR_CONFIG_WIDTH      (0x2UL)

/*! @brief IPWM status clear mask */
#define IPWM_STATUS_CLR_Msk              (0xFF00FFUL)

/*! @brief IPWM all channel overflow flag */
#define IPWM_STATUS_ALL_CHCOF_Msk        (0xF0000UL)

/*! @brief IPWM all channel underflow flag */
#define IPWM_STATUS_ALL_CHCUF_Msk        (0xF00000UL)

/*! @brief IPWM phase z event clear flag */
#define IPWM_STATUS_ALL_CHCUF_Msk        (0xF00000UL)

/*******APIs*******************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Set the IPWM global prescaler value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] globalPsc: Global prescaler value
 * @return None
 */
static inline void IPWM_REG_SetGlobalPscVal(IPWM_Type* regBase, uint8_t globalPsc)
{
    regBase->GPSC = (regBase->GPSC & ~IPWM_GPSC_GPSC_Msk) | (uint32_t)globalPsc;
}

/*!
 * @brief Enable/Disable the IPWM global prescaler
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable global prescaler
 *            - false: Disable global prescaler
 * @return None
 */
static inline void IPWM_REG_SetGlobalPscEn(IPWM_Type* regBase, bool enable)
{
    regBase->GPSC = (regBase->GPSC & ~IPWM_GPSC_GPSCEN_Msk)
                    | ((uint32_t)enable << IPWM_GPSC_GPSCEN_Pos);
}

/*!
 * @brief Enable/Disable the IPWM counter
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable counter
 *            - false: Disable counter
 * @return None
 */
static inline void IPWM_REG_SetCntEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CNTSC[channel] = (regBase->CNTSC[channel] & ~IPWM_CNT0SC_CNTEN_Msk)
                              | ((uint32_t)enable << IPWM_CNT0SC_CNTEN_Pos);
}

/*!
 * @brief Set IPWM count mode
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] mode
 *            - 0: IPWM_UP_COUNT
 *            - 1: IPWM_UP_DOWN_COUNT
 * @return None
 */
static inline void IPWM_REG_SetCntMode(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_count_mode_t mode)
{
    regBase->CNTSC[channel] = (regBase->CNTSC[channel] & ~IPWM_CNT0SC_CPWMS_Msk)
                              | ((uint32_t)mode << IPWM_CNT0SC_CPWMS_Pos);
}

/*!
 * @brief Enable/Disable the IPWM overflow interrupt
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the overflow interrupt
 *            - false: Disable the overflow interrupt
 * @return None
 */
static inline void IPWM_REG_SetOverflowIntEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CNTSC[channel] = (regBase->CNTSC[channel] & ~IPWM_CNT0SC_COIE_Msk)
                              | ((uint32_t)enable << IPWM_CNT0SC_COIE_Pos);
}

/*!
 * @brief Enable/Disable the IPWM underflow interrupt
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the underflow interrupt
 *            - false: Disable the underflow interrupt
 * @return None
 */
static inline void IPWM_REG_SetUnderflowIntEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CNTSC[channel] = (regBase->CNTSC[channel] & ~IPWM_CNT0SC_CUIE_Msk)
                              | ((uint32_t)enable << IPWM_CNT0SC_CUIE_Pos);
}

/*!
 * @brief Set the IPWM overflow & underflow interrupt event ratio
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ratio: Event ratio
 * @return None
 */
static inline void IPWM_REG_SetOverflowEventRatio(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t ratio)
{
    uint32_t regValue = regBase->CNTSC[channel] ;

    regValue &= ~IPWM_CNT0SC_COFNUM_Msk;
    regValue |= (((uint32_t)ratio << IPWM_CNT0SC_COFNUM_Pos) & IPWM_CNT0SC_COFNUM_Msk);
    regBase->CNTSC[channel] = regValue;
}

/*!
 * @brief Clear the IPWM overflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return None
 */
static inline void IPWM_REG_ClrOverflowFlag(IPWM_Type* regBase, ipwm_channel_t channel)
{
    regBase->CNTSC[channel] |= IPWM_CNT0SC_COF_Msk;
}

/*!
 * @brief Get the IPWM overflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Overflow flag
 *         - true: Has overflowed
 *         - false: Has not overflowed
 */
static inline bool IPWM_REG_GetOverflowFlag(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = (regBase->CNTSC[channel] & IPWM_CNT0SC_COF_Msk) >> IPWM_CNT0SC_COF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Clear the IPWM underflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return None
 */
static inline void IPWM_REG_ClrUnderflowFlag(IPWM_Type* regBase, ipwm_channel_t channel)
{
    regBase->CNTSC[channel] |= IPWM_CNT0SC_CUF_Msk;
}

/*!
 * @brief Get the IPWM underflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Underflow flag
 *         - true: Has underflowed
 *         - false: Has not underflowed
 */
static inline bool IPWM_REG_GetUnderflowFlag(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = (regBase->CNTSC[channel] & IPWM_CNT0SC_CUF_Msk) >> IPWM_CNT0SC_CUF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Set the IPWM local prescaler value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] localPsc: Local prescaler value
 * @return None
 */
static inline void IPWM_REG_SetLocalPrescaler(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t localPsc)
{
    uint32_t regValue = regBase->CNTSC[channel];

    regValue &= ~IPWM_CNT0SC_LPSC_Msk;
    regValue |= (((uint32_t)localPsc << IPWM_CNT0SC_LPSC_Pos) & IPWM_CNT0SC_LPSC_Msk);
    regBase->CNTSC[channel] = regValue;
}

/*!
 * @brief Set the IPWM counter value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] cntValue: counter value
 * @return None
 */
static inline void IPWM_REG_SetCounter(IPWM_Type* regBase, ipwm_channel_t channel, uint16_t cntValue)
{
    regBase->CHCNT[channel] = (uint32_t)cntValue;
}

/*!
 * @brief Get the IPWM counter current value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Counter current value
 */
static inline uint16_t IPWM_REG_GetCounter(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CHCNT[channel];

    return (uint16_t)regValue;
}

/*!
 * @brief Set the IPWM counter modulo value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] modValue: Counter modulo value
 * @return None
 */
static inline void IPWM_REG_SetMod(IPWM_Type* regBase, ipwm_channel_t channel, uint16_t modValue)
{
    regBase->CHMOD[channel] = (uint32_t)modValue;
}

/*!
 * @brief Get the IPWM counter modulo value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Counter modulo value
 */
static inline uint16_t IPWM_REG_GetMod(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CHMOD[channel];

    return (uint16_t)regValue;
}

/*!
 * @brief Set the IPWM counter initial value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] initVal: Counter initial value
 * @return None
 */
static inline void IPWM_REG_SetCntInitVal(IPWM_Type* regBase, ipwm_channel_t channel, uint16_t initVal)
{
    regBase->CHCNTIN[channel] = (uint32_t)initVal;
}

/*!
 * @brief Get the IPWM counter initial value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Counter initial value
 */
static inline uint16_t IPWM_REG_GetCntInitVal(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CHCNTIN[channel];

    return (uint16_t)regValue;
}

/*!
 * @brief Enable/Disable the IPWM channel event a reset function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event a reset
 *            - false: Disable the channel event a reset
 * @return None
 */
static inline void IPWM_REG_SetChEventaReset(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_ICaRST_Msk)
                             | ((uint32_t)enable << IPWM_CH0SC_ICaRST_Pos);
}

/*!
 * @brief Enable/Disable the IPWM channel event b reset function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event b reset
 *            - false: Disable the channel event b reset
 * @return None
 */
static inline void IPWM_REG_SetChEventbReset(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_ICbRST_Msk)
                             | ((uint32_t)enable << IPWM_CH0SC_ICbRST_Pos);
}

/*!
 * @brief Set the IPWM Channel value a match dir
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] dir
 *            - 0: IPWM_MATCH_DIR_DOWN
 *            - 1: IPWM_MATCH_DIR_UP
 * @return None
 */
static inline void IPWM_REG_SetCVaMatchDir(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_match_dir_t dir)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_DIRa_Msk)
                             | ((uint32_t)dir << IPWM_CH0SC_DIRa_Pos);
}

/*!
 * @brief Set the IPWM Channel value b match dir
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] dir
 *            - 0: IPWM_MATCH_DIR_DOWN
 *            - 1: IPWM_MATCH_DIR_UP
 * @return None
 */
static inline void IPWM_REG_SetCVbMatchDir(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_match_dir_t dir)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_DIRb_Msk)
                             | ((uint32_t)dir << IPWM_CH0SC_DIRb_Pos);
}

/*!
 * @brief Set the IPWM event a edge level
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] level: 00, 01, 10, 11
 * @return None
 */
static inline void IPWM_REG_SetEventaEdgeLevel(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t levelMode)
{
    uint32_t regValue = regBase->CHSC[channel];

    regValue &= ~IPWM_CH0SC_ELSa_Msk;
    regValue |= (((uint32_t)levelMode << IPWM_CH0SC_ELSa_Pos) & IPWM_CH0SC_ELSa_Msk);
    regBase->CHSC[channel] = regValue;
}

/*!
 * @brief Set the IPWM event b edge level
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] level: 00, 01, 10, 11
 * @return None
 */
static inline void IPWM_REG_SetEventbEdgeLevel(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t levelMode)
{
    uint32_t regValue = regBase->CHSC[channel];

    regValue &= ~IPWM_CH0SC_ELSb_Msk;
    regValue |= (((uint32_t)levelMode << IPWM_CH0SC_ELSb_Pos) & IPWM_CH0SC_ELSb_Msk);
    regBase->CHSC[channel] = regValue;
}

/*!
 * @brief Set the IPWM channel work mode
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] mode
 *            - 0: IPWM_DUAL_EDGE_CAPTURE_CONTINOUS_MODE
 *            - 1: IPWM_DUAL_EDGE_CAPTURE_ONE_SHOT_MODE
 *            - 2: IPWM_COMBINE_OUTPUT_CONTINOUS_MODE
 *            - 3: IPWM_COMBINE_OUTPUT_ONE_SHOT_MODE
 * @return None
 */
static inline void IPWM_REG_SetChMode(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_channel_mode_t mode)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_MSEL_Msk)
                             | ((uint32_t)mode << IPWM_CH0SC_MSEL_Pos);
}

/*!
 * @brief Set the IPWM channel interrupt event a ratio
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ratio
 *            - 0: IPWM_CH_EVENT_RATIO_1
 *            - 1: IPWM_CH_EVENT_RATIO_2
 *            - 2: IPWM_CH_EVENT_RATIO_4
 *            - 3: IPWM_CH_EVENT_RATIO_8
 * @return None
 */
static inline void IPWM_REG_SetChEventaRatio(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_ch_event_ratio_t ratio)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_CHFaPSC_Msk)
                             | ((uint32_t)ratio << IPWM_CH0SC_CHFaPSC_Pos);
}

/*!
 * @brief Set the IPWM channel interrupt event b ratio
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ratio
 *            - 0: IPWM_CH_EVENT_RATIO_1
 *            - 1: IPWM_CH_EVENT_RATIO_2
 *            - 2: IPWM_CH_EVENT_RATIO_4
 *            - 3: IPWM_CH_EVENT_RATIO_8
 * @return None
 */
static inline void IPWM_REG_SetChEventbRatio(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_ch_event_ratio_t ratio)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_CHFbPSC_Msk)
                             | ((uint32_t)ratio << IPWM_CH0SC_CHFbPSC_Pos);
}

/*!
 * @brief Enable/Disable the IPWM channel event a interrupt
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event a interrupt
 *            - false: Disable the channel event a interrupt
 * @return None
 */
static inline void IPWM_REG_SetChEventaIntEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_CHIEa_Msk)
                             | ((uint32_t)enable << IPWM_CH0SC_CHIEa_Pos);
}

/*!
 * @brief Enable/Disable the IPWM channel event b interrupt
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event b interrupt
 *            - false: Disable the channel event b interrupt
 * @return None
 */
static inline void IPWM_REG_SetChEventbIntEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    regBase->CHSC[channel] = (regBase->CHSC[channel] & ~IPWM_CH0SC_CHIEb_Msk)
                             | ((uint32_t)enable << IPWM_CH0SC_CHIEb_Pos);
}

/*!
 * @brief Clear the IPWM channel event a interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return None
 */
static inline void IPWM_REG_ClrChFlaga(IPWM_Type* regBase, ipwm_channel_t channel)
{
    regBase->CHSC[channel] |= IPWM_CH0SC_CHFa_Msk;
}

/*!
 * @brief Get the IPWM channel event a interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Channel event a interrupt flag
 *         - true: Has occured channel event a
 *         - false: Has not occured channel event a
 */
static inline bool IPWM_REG_GetChFlaga(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = (regBase->CHSC[channel] & IPWM_CH0SC_CHFa_Msk) >> IPWM_CH0SC_CHFa_Pos;

    return (bool)regValue;
}

/*!
 * @brief Clear the IPWM channel event b interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return None
 */
static inline void IPWM_REG_ClrChFlagb(IPWM_Type* regBase, ipwm_channel_t channel)
{
    regBase->CHSC[channel] |= IPWM_CH0SC_CHFb_Msk;
}

/*!
 * @brief Get the IPWM channel event b interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Channel event b interrupt flag
 *         - true: Has occured channel event b
 *         - false: Has not occured channel event b
 */
static inline bool IPWM_REG_GetChFlagb(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = (regBase->CHSC[channel] & IPWM_CH0SC_CHFb_Msk) >> IPWM_CH0SC_CHFb_Pos;

    return (bool)regValue;
}

/*!
 * @brief Set the IPWM channel value a
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] chVal: Channel value
 * @return None
 */
static inline void IPWM_REG_SetCVa(IPWM_Type* regBase, ipwm_channel_t channel, uint16_t chVal)
{
    regBase->CHVAL[channel].CVa = (uint32_t)chVal;
}

/*!
 * @brief Get the IPWM channel value a
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Channel value a
 */
static inline uint16_t IPWM_REG_GetCVa(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CHVAL[channel].CVa & IPWM_CH0CVa_CVa_Msk;

    return (uint16_t)regValue;
}

/*!
 * @brief Set the IPWM channel value b
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] chVal: Channel value
 * @return None
 */
static inline void IPWM_REG_SetCVb(IPWM_Type* regBase, ipwm_channel_t channel, uint16_t chVal)
{
    regBase->CHVAL[channel].CVb = (uint32_t)chVal;
}

/*!
 * @brief Get the IPWM channel value b
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @return Channel value b
 */
static inline uint16_t IPWM_REG_GetCVb(IPWM_Type* regBase, ipwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CHVAL[channel].CVb & IPWM_CH0CVb_CVb_Msk;

    return (uint16_t)regValue;
}

/*!
 * @brief Get the IPWM all channel event status
 *
 * @param[in] regBase: The IPWM register base address
 * @return All channel event status
 */
static inline uint8_t IPWM_REG_GetChStatus(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->STATUS & IPWM_STATUS_CHF_Msk;

    return (uint8_t)regValue;
}

/*!
 * @brief Clear the IPWM channel event status
 *
 * @param[in] regBase: The PWM register base address
 * @param[in] chMask: Channel mask
 * @return None
 */
static inline void IPWM_REG_ClrChStatus(IPWM_Type* regBase, uint8_t chMask)
{
    regBase->STATUS = (regBase->STATUS & ~IPWM_STATUS_CLR_Msk) | (uint32_t)chMask;
}

/*!
 * @brief Get the IPWM all channel level
 *
 * @param[in] regBase: The IPWM register base address
 * @return All channel level
 */
static inline uint8_t IPWM_REG_GetChLevel(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->STATUS & IPWM_STATUS_LVL_Mask) >> IPWM_STATUS_CH0LVL_Pos;

    return (uint8_t)regValue;
}

/*!
 * @brief Clear the IPWM all channel overflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] chMsk: channel mask
 * @return None
 */
static inline void IPWM_REG_ClrAllChOverflowFlag(IPWM_Type* regBase, uint8_t chMsk)
{
    uint32_t regValue = regBase->STATUS;

    regValue &= ~IPWM_STATUS_CLR_Msk;
    regValue |= (((uint32_t)chMsk << IPWM_STATUS_CH0COF_Pos) & IPWM_STATUS_ALL_CHCOF_Msk);
    regBase->STATUS = regValue;
}

/*!
 * @brief Get the IPWM all channel overflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @return All channel overflow flag
 */
static inline uint8_t IPWM_REG_GetAllChOverflowFlag(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->STATUS & IPWM_STATUS_ALL_CHCOF_Msk) >> IPWM_STATUS_CH0COF_Pos;

    return (uint8_t)regValue;
}

/*!
 * @brief Clear the IPWM all channel underflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] chMsk: channel mask
 * @return None
 */
static inline void IPWM_REG_ClrAllChUnderflowFlag(IPWM_Type* regBase, uint8_t chMsk)
{
    uint32_t regValue = regBase->STATUS;

    regValue &= ~IPWM_STATUS_CLR_Msk;
    regValue |= (((uint32_t)chMsk << IPWM_STATUS_CH0CUF_Pos) & IPWM_STATUS_ALL_CHCUF_Msk);
    regBase->STATUS = regValue;
}

/*!
 * @brief Get the IPWM all channel underflow interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @return All channel overflow flag
 */
static inline uint8_t IPWM_REG_GetAllChUnderflowFlag(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->STATUS & IPWM_STATUS_ALL_CHCUF_Msk) >> IPWM_STATUS_CH0CUF_Pos;

    return (uint8_t)regValue;
}

/*!
 * @brief Enable/Disable the IPWM register sync
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable register sync
 *            - false: Disable register sync
 * @return None
 */
static inline void IPWM_REG_SetSyncEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->MODE;

    regValue &= ~(IPWM_MODE_SYNCEN0_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_MODE_SYNCEN0_Pos + (uint32_t) channel));
    regBase->MODE = regValue;
}

/*!
 * @brief Enable/Disable the IPWM write protect
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the write protect
 *            - false: Disable the write protect
 * @return None
 */
static inline void IPWM_REG_SetWriteProtect(IPWM_Type* regBase, bool enable)
{
    if (enable) {
        regBase->SYNC |= IPWM_SYNC_WPEN_Msk;
    } else {
        regBase->MODE |= IPWM_MODE_WPDIS_Msk;
    }
}

/*!
 * @brief Enable/Disable the IPWM register read from sync buffer
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Read from sync buffer
 *            - false: Read out the actual active register configuration
 * @return None
 */
static inline void IPWM_REG_SetReadBuff(IPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~IPWM_MODE_BUFFRD_Msk)
                    | ((uint32_t)enable << IPWM_MODE_BUFFRD_Pos);
}

/*!
 * @brief Enable/Disable the IPWM output init function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the output init
 *            - false: Disable the output init
 * @return None
 */
static inline void IPWM_REG_SetOutputInit(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->MODE;

    regValue &= ~(IPWM_MODE_CH0INIT_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_MODE_CH0INIT_Pos + (uint32_t)channel));
    regBase->MODE = regValue;
}

/*!
 * @brief Set the IPWM output init level
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] level
 *            - 0: IPWM_LOW_LEVEL
 *            - 1: IPWM_HIGH_LEVEL
 * @return None
 */
static inline void IPWM_REG_SetOutputInitLevel(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_output_level_t level)
{
    uint32_t regValue = regBase->OUTINIT;

    regValue &= ~(IPWM_OUTINIT_CH0OI_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)level << (IPWM_OUTINIT_CH0OI_Pos + (uint32_t)channel));
    regBase->OUTINIT = regValue;
}

/*!
 * @brief Enable/Disable the IPWM hall mode
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable hall mode
 *            - false: Disable hall mode
 * @return None
 */
static inline void IPWM_REG_SetHallMode(IPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~IPWM_MODE_HALL_Msk)
                    | ((uint32_t)enable << IPWM_MODE_HALL_Pos);
}

/*!
 * @brief Enable/Disable the IPWM min load point
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the min load point
 *            - false: Disable the min load point
 * @return None
 */
static inline void IPWM_REG_SetMinLoadPoint(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNC;

    regValue &= ~(IPWM_SYNC_CNT0MIN_Msk << ((uint32_t)channel * IPWM_SYNC_POINT_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_SYNC_CNT0MIN_Pos + (uint32_t)channel * IPWM_SYNC_POINT_WIDTH));
    regBase->SYNC = regValue;
}

/*!
 * @brief Enable/Disable the IPWM max load point
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the max load point
 *            - false: Disable the max load point
 * @return None
 */
static inline void IPWM_REG_SetMaxLoadPoint(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNC;

    regValue &= ~(IPWM_SYNC_CNT0MAX_Msk << ((uint32_t)channel * IPWM_SYNC_POINT_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_SYNC_CNT0MAX_Pos + (uint32_t)channel * IPWM_SYNC_POINT_WIDTH));
    regBase->SYNC = regValue;
}

/*!
 * @brief Set software trigger to sync register
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Set Software trigger signal to high
 *            - false: Set Software trigger signal to low
 * @return None
 */
static inline void IPWM_REG_SetSoftwareTriggerSync(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNC;

    regValue &= ~(IPWM_SYNC_CH0SWSYNC_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_SYNC_CH0SWSYNC_Pos + (uint32_t)channel));
    regBase->SYNC = regValue;
}

/*!
 * @brief Enable/Disable the IPWM output mask function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the output mask
 *            - false: Disable the output mask
 * @return None
 */
static inline void IPWM_REG_SetOutputMask(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->OUTMASK;

    regValue &= ~(IPWM_OUTMASK_CH0OM_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_OUTMASK_CH0OM_Pos + (uint32_t)channel));
    regBase->OUTMASK = regValue;
}

/*!
 * @brief Set the IPWM channel polarity
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] polarity
 *            - 0: IPWM_OUTPUT_POLARITY_ACTIVE_HIGH
 *            - 1: IPWM_OUTPUT_POLARITY_ACTIVE_LOW
 * @return None
 */
static inline void IPWM_REG_SetChPOL(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_active_output_polarity_t polarity)
{
    uint32_t regValue = regBase->POL;

    regValue &= ~(IPWM_POL_CH0POL_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)polarity << (IPWM_POL_CH0POL_Pos + (uint32_t)channel));
    regBase->POL = regValue;
}

/*!
 * @brief Enable/Disable the IPWM software control function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the software control
 *            - false: Disable the software control
 * @return None
 */
static inline void IPWM_REG_SetSoftwareControlEn(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SWOCTRL;

    regValue &= ~(IPWM_SWOCTRL_CH0OC_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_SWOCTRL_CH0OC_Pos + (uint32_t)channel));
    regBase->SWOCTRL = regValue;
}

/*!
 * @brief Set the IPWM software control level
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] polarity
 *            - 0: IPWM_LOW_LEVEL
 *            - 1: IPWM_HIGH_LEVEL
 * @return None
 */
static inline void IPWM_REG_SetSoftwareControlLevel(IPWM_Type* regBase, ipwm_channel_t channel, ipwm_output_level_t level)
{
    uint32_t regValue = regBase->SWOCTRL;

    regValue &= ~(IPWM_SWOCTRL_CH0OCV_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)level << (IPWM_SWOCTRL_CH0OCV_Pos + (uint32_t)channel));
    regBase->SWOCTRL = regValue;
}

/*!
 * @brief Enable/Disable the IPWM Min trigger
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the min trigger
 *            - false: Disable the min trigger
 * @return None
 */
static inline void IPWM_REG_SetMinTrigger(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->EXTTRIG;

    regValue &= ~(IPWM_EXTTRIG_CH0MINTRIG_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_EXTTRIG_CH0MINTRIG_Pos + (uint32_t)channel));
    regBase->EXTTRIG = regValue;
}

/*!
 * @brief Enable/Disable the IPWM max trigger
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the max trigger
 *            - false: Disable the max trigger
 * @return None
 */
static inline void IPWM_REG_SetMaxTrigger(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->EXTTRIG;

    regValue &= ~(IPWM_EXTTRIG_CH0MAXTRIG_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (IPWM_EXTTRIG_CH0MAXTRIG_Pos + (uint32_t)channel));
    regBase->EXTTRIG = regValue;
}

/*!
 * @brief Enable/Disable the IPWM channel event a match trigger
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event a match trigger
 *            - false: Disable the channel event a match trigger
 * @return None
 */
static inline void IPWM_REG_SetCVaMatchTrigger(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->EXTTRIG;

    regValue &= ~(IPWM_EXTTRIG_CH0MATCHTRIGa_Msk << ((uint32_t)channel * IPWM_MATCH_DIR_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_EXTTRIG_CH0MATCHTRIGa_Pos + (uint32_t)channel * IPWM_MATCH_DIR_CONFIG_WIDTH));
    regBase->EXTTRIG = regValue;
}

/*!
 * @brief Enable/Disable the IPWM channel event b match trigger
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the channel event b match trigger
 *            - false: Disable the channel event b match trigger
 * @return None
 */
static inline void IPWM_REG_SetCVbMatchTrigger(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->EXTTRIG;

    regValue &= ~(IPWM_EXTTRIG_CH0MATCHTRIGb_Msk << ((uint32_t)channel * IPWM_MATCH_DIR_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_EXTTRIG_CH0MATCHTRIGb_Pos + (uint32_t)channel * IPWM_MATCH_DIR_CONFIG_WIDTH));
    regBase->EXTTRIG = regValue;
}

/*!
 * @brief Set the IPWM external trigger ratio
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] ratio
 *            - 0: IPWM_TRIGGER_RATIO_1
 *            - 1: IPWM_TRIGGER_RATIO_2
 *            - 2: IPWM_TRIGGER_RATIO_3
 *            - 3: IPWM_TRIGGER_RATIO_4
 *            - 4: IPWM_TRIGGER_RATIO_5
 *            - 5: IPWM_TRIGGER_RATIO_6
 *            - 6: IPWM_TRIGGER_RATIO_7
 *            - 7: IPWM_TRIGGER_RATIO_8
 * @return None
 */
static inline void IPWM_REG_SetExternalTriggerRatio(IPWM_Type* regBase, ipwm_trigger_ratio_t ratio)
{
    regBase->EXTTRIG = (regBase->EXTTRIG & ~IPWM_EXTTRIG_TRIGPSC_Msk)
                       | ((uint32_t)ratio << IPWM_EXTTRIG_TRIGPSC_Pos);
}

/*!
 * @brief Set the IPWM input filter value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] filterVal: Input filter value
 * @return None
 */
static inline void IPWM_REG_SetInputFilterVal(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t filterVal)
{
    uint32_t regValue = regBase->FILTER;

    regValue &= ~(IPWM_FILTER_CH0FVAL_Msk << (IPWM_FILTER_CH1FVAL_Pos * (uint32_t)channel));
    regValue |= ((uint32_t)filterVal << (IPWM_FILTER_CH1FVAL_Pos * (uint32_t)channel));
    regBase->FILTER = regValue;
}

/*!
 * @brief Set the IPWM input filter prescaler value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] filterVal: Input filter prescaler value
 * @return None
 */
static inline void IPWM_REG_SetInputFilterPsc(IPWM_Type* regBase, ipwm_input_filter_psc_t filtePsc)
{
    regBase->FILTER = (regBase->FILTER & ~IPWM_FILTER_FILTPSC_Msk)
                      | ((uint32_t)filtePsc << IPWM_FILTER_FILTPSC_Pos);
}

/*!
 * @brief Enable/Disable the IPWM quad decoder
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the quad decoder
 *            - false: Disable the quad decoder
 * @return None
 */
static inline void IPWM_REG_SetQuadDecoder(IPWM_Type* regBase, bool enable)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_QUADEN_Msk)
                      | ((uint32_t)enable << IPWM_QDCTRL_QUADEN_Pos);
}
#if (CONFIG_IPWM_SUPPORT_DECODER_DIR == 1U)
/*!
 * @brief Enable/Disable the IPWM quad decoder
 *
 * @param[in] regBase: The IPWM register base address
 * @return quad decoder counter direction
 */
static inline bool IPWM_REG_GetQuadDecoderDir(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->QDCTRL & IPWM_QDCTRL_QUADIR_Msk) >> IPWM_QDCTRL_QUADIR_Pos;

    return (bool)regValue;
}
#endif
/*!
 * @brief Set the IPWM quad decoder mode
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] mode
 *            - 0: IPWM_QUAD_PHASE_ENCODE
 *            - 1: IPWM_QUAD_COUNT_DIR
 * @return None
 */
static inline void IPWM_REG_SetQuadDecoderMode(IPWM_Type* regBase, ipwm_quad_decode_mode_t mode)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_QUADMODE_Msk)
                      | ((uint32_t)mode << IPWM_QDCTRL_QUADMODE_Pos);
}

/*!
 * @brief Set the IPWM phase A polarity
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] polarity
 *            - 0: IPWM_QUAD_PHASE_NORMAL
 *            - 1: IPWM_QUAD_PHASE_INVERT
 * @return None
 */
static inline void IPWM_REG_SetPhaseAPolarity(IPWM_Type* regBase, ipwm_quad_phase_polarity_t polarity)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_PHAPOL_Msk)
                      | ((uint32_t)polarity << IPWM_QDCTRL_PHAPOL_Pos);
}

/*!
 * @brief Set the IPWM phase B polarity
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] polarity
 *            - 0: IPWM_QUAD_PHASE_NORMAL
 *            - 1: IPWM_QUAD_PHASE_INVERT
 * @return None
 */
static inline void IPWM_REG_SetPhaseBPolarity(IPWM_Type* regBase, ipwm_quad_phase_polarity_t polarity)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_PHBPOL_Msk)
                      | ((uint32_t)polarity << IPWM_QDCTRL_PHBPOL_Pos);
}

/*!
 * @brief Set the IPWM phase Z polarity
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] polarity
 *            - 0: IPWM_QUAD_PHASE_NORMAL
 *            - 1: IPWM_QUAD_PHASE_INVERT
 * @return None
 */
static inline void IPWM_REG_SetPhaseZPolarity(IPWM_Type* regBase, ipwm_quad_phase_polarity_t polarity)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_PHZPOL_Msk)
                      | ((uint32_t)polarity << IPWM_QDCTRL_PHZPOL_Pos);
}

/*!
 * @brief Enable/Disable the IPWM phase Z event reset
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the phase Z event reset
 *            - false: Disable the phase Z event reset
 * @return None
 */
static inline void IPWM_REG_SetPhaseZReset(IPWM_Type* regBase, bool enable)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_PHZRST_Msk)
                      | ((uint32_t)enable << IPWM_QDCTRL_PHZRST_Pos);
}

/*!
 * @brief Get the IPWM phase Z event status
 *
 * @param[in] regBase: The IPWM register base address
 * @return Phase Z event status
 *         - true: Has occured phase Z event
 *         - false: Has not occured phase Z event
 */
static inline bool IPWM_REG_GetPhaseZStatus(IPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->QDCTRL & IPWM_QDCTRL_PHZSTS_Msk) >> IPWM_QDCTRL_PHZSTS_Pos;

    return (bool)regValue;
}

/*!
 * @brief Clear the IPWM phase z interrupt flag
 *
 * @param[in] regBase: The IPWM register base address
 * @return None
 */
static inline void IPWM_REG_ClrPhaseZStatus(IPWM_Type* regBase)
{
    uint32_t regValue = regBase->QDCTRL;

    regValue &= ~IPWM_QDCTRL_PHZSTS_Msk;
    regValue |= IPWM_QDCTRL_PHZSTS_Msk;
    regBase->QDCTRL = regValue;
}

#if (CONFIG_IPWM_SUPPORT_PHASEZ_INT == 1U)
/*!
 * @brief Enable/Disable the IPWM phase Z event interrupt
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the phase Z event interrupt
 *            - false: Disable the phase Z event interrupt
 * @return None
 */
static inline void IPWM_REG_SetPhaseZIntEnable(IPWM_Type* regBase, bool enable)
{
    regBase->QDCTRL = (regBase->QDCTRL & ~IPWM_QDCTRL_PHZIE_Msk)
                      | ((uint32_t)enable << IPWM_QDCTRL_PHZIE_Pos);
}
#endif

/*!
 * @brief Enable/Disable the IPWM Cnv sync function
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the cnv sync function
 *            - false: Disable the cnv sync function
 * @return None
 */
static inline void IPWM_REG_SetCnvSync(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNCONF;

    regValue &= ~(IPWM_SYNCONF_CH0SYNCEN_Msk << ((uint32_t)channel * IPWM_SYNCONF_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_SYNCONF_CH0SYNCEN_Pos + IPWM_SYNCONF_CONFIG_WIDTH * (uint32_t)channel));
    regBase->SYNCONF = regValue;
}

/*!
 * @brief Enable/Disable the IPWM counter software sync
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the counter software sync
 *            - false: Disable the counter software sync
 * @return None
 */
static inline void IPWM_REG_SetCounterSoftwareSync(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNCONF;

    regValue &= ~(IPWM_SYNCONF_CH0SWRSTCNT_Msk << ((uint32_t)channel * IPWM_SYNCONF_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_SYNCONF_CH0SWRSTCNT_Pos + IPWM_SYNCONF_CONFIG_WIDTH * (uint32_t)channel));
    regBase->SYNCONF = regValue;
}

/*!
 * @brief Enable/Disable the IPWM MOD,CNTIN,CNV software sync
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] enable
 *            - true: Enable the MOD,CNTIN,CNV software sync
 *            - false: Disable the MOD,CNTIN,CNV software sync
 * @return None
 */
static inline void IPWM_REG_SetModSoftwareSync(IPWM_Type* regBase, ipwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SYNCONF;

    regValue &= ~(IPWM_SYNCONF_CH0SWWRBUF_Msk << ((uint32_t)channel * IPWM_SYNCONF_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (IPWM_SYNCONF_CH0SWWRBUF_Pos + IPWM_SYNCONF_CONFIG_WIDTH * (uint32_t)channel));

    regBase->SYNCONF = regValue;
}

/*!
 * @brief Enable/Disable the IPWM global time base
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the global time base
 *            - false: Disable the global time base
 * @return None
 */
static inline void IPWM_REG_SetGlobalTimeBaseEnable(IPWM_Type* regBase, bool enable)
{
    regBase->CONF = (regBase->CONF & ~IPWM_CONF_GTBEEN_Msk)
                    | ((uint32_t)enable << IPWM_CONF_GTBEEN_Pos);
}

/*!
 * @brief Enable/Disable the IPWM global time base ouput
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] enable
 *            - true: Enable the global time base ouput
 *            - false: Disable the global time base ouput
 * @return None
 */
static inline void IPWM_REG_SetGlobalTimeBaseOutput(IPWM_Type* regBase, bool enable)
{
    regBase->CONF = (regBase->CONF & ~IPWM_CONF_GTBEOUT_Msk)
                    | ((uint32_t)enable << IPWM_CONF_GTBEOUT_Pos);
}

/*!
 * @brief Set the IPWM channel value a dither value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ditherVal: channel value a dither value
 * @return None
 */
static inline void IPWM_REG_SetCVaDither(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t ditherVal)
{
    regBase->CHDITHER[channel].CVaDITHER = (ditherVal & IPWM_CH0CVaDITHER_CVaDITHER_Msk);
}

/*!
 * @brief Set the IPWM channel value b dither value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ditherVal: channel value b dither value
 * @return None
 */
static inline void IPWM_REG_SetCVbDither(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t ditherVal)
{
    regBase->CHDITHER[channel].CVbDITHER = (ditherVal & IPWM_CH0CVbDITHER_CVbDITHER_Msk);
}

/*!
 * @brief Set the IPWM modulo dither value
 *
 * @param[in] regBase: The IPWM register base address
 * @param[in] channel: IPWM channel(IPWM_CH0~3)
 * @param[in] ditherVal: modulo dither value
 * @return None
 */
static inline void IPWM_REG_SetModDither(IPWM_Type* regBase, ipwm_channel_t channel, uint8_t ditherVal)
{
    regBase->CHMODDITHER[channel] = (ditherVal & IPWM_CH0MODDITHER_MODDITHER_Msk);
}

#if defined(__cplusplus)
}
#endif

#endif /* IPWM_REG_ACCESS_H */

/*******EOF********************************************************************/

